/* Copyright (c) 2008 LepomisLab.com, Andrey Turkin
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "NSarray.h"
#include "NSKeyedUnarchiver.h"

IMPLEMENT_DYNAMIC_CLASS(NSMutableArray,NSObject)
IMPLEMENT_DYNAMIC_CLASS(NSArray,NSMutableArray)

NSMutableArray::NSMutableArray(wxObject* values[], size_t len) : NSObject()
{
	m_vector.insert(m_vector.end(), values, values+len);
	delete values;
}

NSMutableArray::NSMutableArray() : NSObject()
{
}

NSMutableArray::~NSMutableArray()
{
}

void NSMutableArray::initWithUnarchiver(NSKeyedUnarchiver *archiver)
{
	m_vector.clear();
	wxObject *_k = archiver->decodeArrayObjectForKey(wxT("NS.objects"));
	wxASSERT(_k); /* not sure if missing NS.objects is normal */
	if (_k)
	{
		NSArray *keys = wxDynamicCast(_k, NSArray);
		wxASSERT(keys);
		size_t len = keys->length();
		for(size_t l = 0; l < len; l++)
		{
			wxObject *val = keys->getObject(l);
			wxASSERT(val);
			m_vector.push_back(val);
		}
	} else {
		for(size_t l = 0; ; l++)
		{
			wxString key_n;
			key_n.Format(wxT("NS.object.%u"), l);
			wxObject *val = archiver->decodeObjectForKey(key_n);
			if (!val)
				break;
			m_vector.push_back(val);
		}
	}
}

void NSMutableArray::deleteObject(size_t key)
{
	wxCHECK_RET(key < m_vector.size(), wxT("Subscript out of range"));
	m_vector.erase(m_vector.begin() + key);
}

void NSMutableArray::addObject(wxObject* val)
{
	m_vector.push_back(val);
}

wxObject* NSMutableArray::_getValue(const wxString& key)
{
	if (key.StartsWith(wxT("@")))
	{
		wxCHECK(!key.Contains(wxT(".")), NULL);
		if (key == wxT("@count"))
		{
			return new wxVariant((long)m_vector.size());
		} else
		{
			wxFAIL;
			return NULL;
		}
	} else
	{
		NSMutableArray* new_array = new NSMutableArray();
		wxCHECK(new_array, NULL);
		for(array_vector::const_iterator i = m_vector.begin(); i != m_vector.end(); i++)
		{
			NSObject *obj = wxDynamicCast(*i, NSObject);
			wxCHECK_MSG(obj, NULL, "Trying to get value for non-object");
			new_array->m_vector.push_back(obj->getValue(key));		
		}
		return new_array;
	}
}

void NSMutableArray::_setValue(const wxString& key, wxObject* value)
{
	NSUNUSED(key);
	NSUNUSED(value);
	wxFAIL;
}

wxObject* NSMutableArray::getValueForKeypath(const wxString& keypath)
{
	if (keypath.StartsWith(wxT("@")))
	{
		size_t dot = keypath.find('.');
		wxCHECK(dot != wxString::npos, NULL);
		wxString key(keypath.substr(0,dot));
		wxString parameter(keypath.substr(dot+1));
		if (keypath == wxT("@max"))
		{
			wxFAIL;
			return NULL;
		} else
		{
			wxFAIL;
			return NULL;
		}
	} else
	{
		NSMutableArray* new_array = new NSMutableArray();
		wxCHECK(new_array, NULL);
		for(array_vector::const_iterator i = m_vector.begin(); i != m_vector.end(); i++)
		{
			NSObject *obj = wxDynamicCast(*i, NSObject);
			wxCHECK_MSG(obj, NULL, "Trying to get value for non-object");
			new_array->m_vector.push_back(obj->getValueForKeypath(keypath));		
		}
		return new_array;
	}
}
